package org.yzbdl.lanius.orchestrate.task.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.yzbdl.lanius.orchestrate.common.annotation.auth.CheckPermission;
import org.yzbdl.lanius.orchestrate.common.annotation.log.OprId;
import org.yzbdl.lanius.orchestrate.common.annotation.log.OprLog;
import org.yzbdl.lanius.orchestrate.common.base.controller.BaseController;
import org.yzbdl.lanius.orchestrate.common.constant.UserOprEventConstant;
import org.yzbdl.lanius.orchestrate.common.dto.resource.TaskResourceTreeDto;
import org.yzbdl.lanius.orchestrate.common.dto.task.TaskPlanQueryDTO;
import org.yzbdl.lanius.orchestrate.common.entity.resource.ServerProgramEntity;
import org.yzbdl.lanius.orchestrate.common.entity.resource.TaskResourceEntity;
import org.yzbdl.lanius.orchestrate.common.entity.task.TaskPlan;
import org.yzbdl.lanius.orchestrate.common.result.ResultObj;
import org.yzbdl.lanius.orchestrate.common.vo.task.TaskPlanGroupVO;
import org.yzbdl.lanius.orchestrate.common.vo.task.TaskPlanVO;
import org.yzbdl.lanius.orchestrate.serv.service.resource.TaskResourceGroupService;
import org.yzbdl.lanius.orchestrate.serv.service.resource.TaskResourceService;
import org.yzbdl.lanius.orchestrate.serv.service.task.TaskPlanGroupService;
import org.yzbdl.lanius.orchestrate.serv.service.task.TaskPlanService;

import java.util.List;

/**
 * 任务编排相关接口控制器
 *
 * @author jinchunzhao@yzbdl.ac.cn
 * @version 1.0
 * @date 2022-04-07 10:38
 */
@Slf4j
@Api(value = "任务编排相关接口控制器", tags = "任务编排相关接口控制器")
@RestController
@RequestMapping("/task/plan/")
public class TaskPlanController extends BaseController {

    @Autowired
    private TaskPlanService taskPlanService;

    @Autowired
    private TaskPlanGroupService taskPlanGroupService;

    @Autowired
    private TaskResourceGroupService taskResourceGroupService;

    @Autowired
    private TaskResourceService taskResourceService;

    /**
     * 任务编排分页列表
     *
     * @param page
     *        页码
     * @param size
     *        每页数量
     * @param taskPlanQueryDTO
     *        查询参数
     * @return
     *        结果信息
     */
    @CheckPermission("task::plan::query")
    @RequestMapping(value = "queryPage", method = RequestMethod.POST)
    @ApiOperation(value = "分页列表", notes = "任务编排分页列表")
    @ResponseBody
    public ResultObj<IPage<TaskPlanVO>> queryPage(@RequestParam(defaultValue = "1") Integer page,
        @RequestParam(defaultValue = "20") Integer size, @RequestBody @Validated TaskPlanQueryDTO taskPlanQueryDTO) {
        IPage<TaskPlanVO> iPage = taskPlanService.queryPage(buildIPage(page, size), taskPlanQueryDTO);
        return ResultObj.success(iPage);
    }

    /**
     * 新增任务
     *
     * @param taskPlan
     *        任务编排
     * @return
     *        结果信息
     */
    @OprLog(value = UserOprEventConstant.TASK_PLAN_ADD,msg="新增了任务计划${taskName}")
    @CheckPermission("task::plan::edit")
    @PostMapping(value = "/taskPlan")
    @ApiOperation(value = "新增任务", notes = "新增任务")
    @ResponseBody
    public ResultObj<Boolean> saveEntity(@RequestBody @Validated TaskPlan taskPlan) {
        return ResultObj.success(taskPlanService.saveEntity(taskPlan));
    }

    /**
     * 更新任务
     *
     * @param taskPlan
     *        任务编排
     * @return
     *        结果信息
     */
    @OprLog(value = UserOprEventConstant.TASK_PLAN_UPDATE,msg="更新了任务计划${taskName}")
    @CheckPermission("task::plan::edit")
    @PutMapping(value = "/taskPlan")
    @ApiOperation(value = "更新任务", notes = "更新任务")
    @ResponseBody
    public ResultObj<Boolean> updateEntity(@RequestBody @Validated TaskPlan taskPlan) {
        return ResultObj.success(taskPlanService.updateEntity(taskPlan));
    }

    /**
     * 根据ID删除任务
     *
     * @param id
     *        分组ID
     * @return
     *        结果信息
     * @throws Exception
     *         任何异常
     */
    @OprLog(value = UserOprEventConstant.TASK_PLAN_DELETE,msg="删除了任务计划${taskName}，id是${id}")
    @CheckPermission("task::plan::delete")
    @DeleteMapping(value = "/taskPlan/{id}")
    @ApiOperation(value = "根据ID删除任务", notes = "根据ID删除任务")
    @ResponseBody
    public ResultObj<Boolean> deleteEntity(@PathVariable(value = "id", required = true) @OprId(server = TaskPlanService.class) Long id) throws Exception{
        return ResultObj.success(taskPlanService.deleteEntity(id));
    }

    /**
     * 更新任务状态
     *
     * @param taskId
     *        任务ID
     * @param status
     *        任务状态
     * @return
     *        结果信息
     */
    @OprLog(value = UserOprEventConstant.TASK_PLAN_UPDATE,msg="更新了任务计划${taskName}的状态")
    @CheckPermission("task::plan::edit")
    @PutMapping(value = "/taskStatus/{taskId}/{status}")
    @ApiOperation(value = "更新任务状态", notes = "更新任务状态")
    @ResponseBody
    public ResultObj<Boolean> updateTaskStatus(@PathVariable(value = "taskId") @OprId(server = TaskPlanService.class) Long taskId,
        @PathVariable(value = "status") Integer status) {
        return ResultObj.success(taskPlanService.updateTaskStatus(taskId, status));
    }

    /**
     * 手动执行一次任务
     *
     * @param taskId
     *        任务ID
     * @return
     *        结果信息
     */
    @OprLog(value = UserOprEventConstant.TASK_PLAN_EXECUTE,msg="手动执行了任务计划${taskName}")
    @CheckPermission("task::plan::edit")
    @GetMapping(value = "/executeNow/{taskId}")
    @ApiOperation(value = "手动执行一次任务", notes = "手动执行一次任务")
    @ResponseBody
    public ResultObj executeNow(@PathVariable(value = "taskId") @OprId(server = TaskPlanService.class) Long taskId) {
        taskPlanService.executeNow(taskId);
        return ResultObj.success();
    }

    /**
     * 服务节点列表
     *
     * @return 结果数据
     */
    @CheckPermission("task::plan::query")
    @GetMapping(value = "serverProgramList")
    @ApiOperation(value = "服务节点列表", notes = "服务节点列表")
    @ResponseBody
    public ResultObj<List<ServerProgramEntity>> getServerProgramList() {
        return ResultObj.success(taskPlanService.serverPrograms());
    }

    /**
     * 任务资源分组树型数据
     *
     * @return 结果数据
     */
    @CheckPermission("task::plan::query")
    @GetMapping(value = "taskResourceGroupTree")
    @ApiOperation(value = "任务资源分组树", notes = "任务资源分组树")
    @ResponseBody
    public ResultObj<List<TaskResourceTreeDto>> getTaskResourceGroupTree() {
        return ResultObj.success(taskResourceGroupService.treeListForTaskPlan());
    }

    /**
     * 根据任务资源分组ID获取任务资源列表
     *
     * @return 结果数据
     */
    @CheckPermission("task::plan::query")
    @GetMapping(value = "taskResourceList/{resGroupId}")
    @ApiOperation(value = "根据任务资源分组ID获取任务资源列表", notes = "根据任务资源分组ID获取任务资源列表")
    @ResponseBody
    public ResultObj<List<TaskResourceEntity>>
        getTaskResourceList(@PathVariable(value = "resGroupId", required = true) Long resGroupId) {
        return ResultObj.success(taskResourceService.getListByGroupIdForTaskPlan(resGroupId));
    }

    /**
     * 分组树形结构
     *
     * @return
     *        树形信息
     */
    @CheckPermission("task::plan::query")
    @GetMapping(value = "/group/tree")
    @ApiOperation(value = "任务编排分组树形结构", notes = "任务编排分组树形结构")
    @ResponseBody
    public ResultObj<List<TaskPlanGroupVO>> queryTaskGroupTree() {
        return ResultObj.success(taskPlanGroupService.queryTaskGroupTreeForTaskPlan());
    }

}
